package com.wlstock.funi.dao;

import android.content.Context;

import com.j256.ormlite.dao.Dao;
import com.wlstock.funi.model.OperateModel;
import com.wlstock.funi.model.PositionModel;
import com.wlstock.funi.utils.TimeUtils;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

public class PositionDao {
	
	private Dao<PositionModel, Integer> positionDao ;
	private DataBaseHelper helper;
	private static PositionDao daoInstance;
	private Context mContext;
	
	public static final int ERROR = -1;
	
	@SuppressWarnings("unchecked")
	private PositionDao(Context context){
		mContext = context;
		try {
			helper = DataBaseHelper.getHelper(context);
			positionDao = helper.getDao(PositionModel.class);
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}
	
	public static PositionDao getInstance(Context mContext){
		if (daoInstance == null) {
			synchronized (PositionDao.class) {
				if (daoInstance == null) {
					daoInstance = new PositionDao(mContext);
				}
			}
		}
		return daoInstance;
	}
	
	/**
	 * 只能在获取我的仓位信息的时候调用这个方法,其余地方只能调用更新操作
	 * PositionModel的stockMoney包含了基金以及天天理财等信息,所以不能直接用stockMoney/totalAssert 作为仓位计算
	 * @param model
	 */
	public void addOrUpdatePosition(PositionModel model){
		float position = 1 - model.getUseableFund()/model.getTotalAsserts();
		model.setCurPostion(position);
		try {
			positionDao.createOrUpdate(model);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public List<PositionModel> queryAll(){
		try {
			return positionDao.queryForAll();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	public PositionModel getCurpositionModel(){
		try {
			PositionModel model = positionDao.queryBuilder().queryForFirst();
			return model;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 检查是否最新仓位
	 * @param curDate
	 * @return
     */
	public boolean isNewlyPosition(Date curDate){
		PositionModel model = getCurpositionModel();
		if (!isModelCorrect(model))
			return false;
		return isNewlyPosition(model,curDate);
	}

	/**
	 * 检查是否最新仓位
	 * @param curDate
	 * @return
	 */
	public boolean isNewlyPosition(PositionModel model, Date curDate){
		if (model.getLastUpdate() == null || curDate == null)
			return false;
		return TimeUtils.isDateInPeriodRange(model.getLastUpdate(),curDate, TimeUtils.TIME_PERIOD.MIN,(long)20);
	}

	/**
	 * 返回当前仓位值
	 * 如果获取总资产为0，则返回1000表示异常
	 * @return
	 */
	public float getCurPositionValue(){
		PositionModel model = getCurpositionModel();
		if (model==null || model.getTotalAsserts() <= 0) {
			return ERROR;
		}
		return model.getCurPostion();
	}
	
	/**
	 * 通过买入、卖出的股票数目，价钱更新仓位
	 * @param tradeType
	 * @param tradePty
	 * @param tradePrice
	 */
	public void updateCurPosition(int tradeType, long tradePty, float tradePrice){
		PositionModel positionModel = getCurpositionModel();
		if (isModelCorrect(positionModel)) {
			if (tradeType != OperateModel.TradeType_BUY || tradeType!=OperateModel.TradeType_SELL) {
				return ;
			}
			float tradeMoney = tradePty * tradePrice;
			if (tradeType == OperateModel.TradeType_SELL) {
				tradeMoney = tradeMoney * -1;
			}
			
			float changeMoney = positionModel.getStockMoney() + tradeMoney;
			float userAbleMoney   = positionModel.getUseableFund() - tradeMoney;
			if (changeMoney > positionModel.getTotalAsserts()) {
				return ;
			}
			positionModel.setStockMoney(changeMoney);
			positionModel.setUseableFund(userAbleMoney);
			positionModel.setCurPostion( 1- userAbleMoney/positionModel.getTotalAsserts());
			try {
				positionDao.update(positionModel);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 判断model是否正确，如果仓位信息为空则应该抛出异常
	 * @param positionModel
	 * @return
	 */
	private boolean isModelCorrect(PositionModel positionModel) {
		
		if (positionModel ==null ||positionModel.getTotalAsserts() == 0) {
			return false;
		}
		return true;
	}
	
	/**
	 * 是否可以买入
	 * @param tradePty 数量
	 * @param tradePrice 价格
	 * @param limitPosition 仓位上限
	 * @return
	 */
	public boolean couldBuy(long tradePty, float tradePrice, float limitPosition){
//		PositionModel model = getCurpositionModel();
//		if (isModelCorrect(model)) {
//			float limitAsserts = model.getTotalAsserts() * limitPosition ;
//			float chanedAsserts = tradePty * tradePrice + model.getStockMoney();
//			if (chanedAsserts > limitAsserts) {
//				return false;
//			}else {
//				return true;
//			}
//		}
		return true;
	}

	public long getBuyAbleMoney(float expectPostion) {
		PositionModel model = getCurpositionModel();
		if (isModelCorrect(model)){
			float curPostion = model.getCurPostion();
			if (expectPostion < curPostion)
				return 0;
			int money = (int)((expectPostion - curPostion)*model.getTotalAsserts());
			return money;
		}
		return 0;
	}

	/**
	 * 只更新总市值
	 * @param totalAssert
     */
	public void upDateTotalAssert(float totalAssert) {
		PositionModel curpositionModel = getCurpositionModel();
		curpositionModel.setLastUpdate(new Date());
		curpositionModel.setTotalAsserts(totalAssert);
		this.addOrUpdatePosition(curpositionModel);
	}
}
